﻿using System;

namespace SoftwareConsulting.BI11.NumericalMethods.Iterations
{
    /// <summary>
    /// Класс неограниченного ряда
    /// </summary>
    public abstract class InifiniteSeries : IterativeProcess
    {	    
        private double _sum;//сумма, к которой сходится ряд
        private double _x;//аргумент ряда    	
        private double _lastTerm;//последнее слагаемое

        /// <summary>
        /// Возвращает/устанавливает последнее слагаемое
        /// </summary>
        protected double LastTerm
        {
            get
            {
                return _lastTerm;
            }
            set
            {
                _lastTerm = value;
            }
        }

        /// <summary>
        /// Вычисляет указанное слагаемое ряда и сохраняет в соответствующей переменной
        /// </summary>
        /// <param name="termIndex"></param>
        protected abstract void ComputeTermAt(int termIndex);

        /// <summary>
        /// Выполняет проход по ряду
        /// </summary>
        /// <returns>относительная ошибка</returns>
        public override double DoIteration()
        {
            ComputeTermAt(IterationsCount);
            _sum += _lastTerm;
            return GetRelativeError(Math.Abs(_lastTerm), Math.Abs(_sum));
        }

        /// <summary>
        /// Возвращает сумму, к которой сходится ряд
        /// </summary>
        public double Sum
        {
            get 
            { 
                return _sum; 
            }
        }

        /// <summary>
        /// Устанавливает начальное состояние ряда
        /// </summary>
        public override void CreateRandomPopulation()
        {
            _sum = InitialValue();
        }

        /// <summary>
        /// Возвращает нулевое слагаемое ряда
        /// </summary>
        /// <returns></returns>
        protected abstract double InitialValue();

        /// <summary>
        /// Возвращает/устанавливает аргумент ряда
        /// </summary>
        public double Argument
        {
            get
            {
                return _x;
            }
            set 
            { 
                _x = value; 
            }
        }
    }
}
